package beanstao.util.services;

import java.util.concurrent.atomic.AtomicBoolean;

import beanstao.util.Util;
import beanstao.util.log.LogHelper;

/**
 * 一个实现IService接口的抽象基类。
 */
public abstract class AbstractService implements IService
{

	private final AtomicBoolean	isStarted;
	private final ServiceType	type;

	public AbstractService(final ServiceType type)
	{
		this.type = Util.notNull(type);
		isStarted = new AtomicBoolean(false);
	}

	public ServiceType getType()
	{
		return type;
	}

	public boolean isStarted()
	{
		return isStarted.get();
	}

	public void startService()
	{
		boolean isntStarted = isStarted.compareAndSet(false, true);
		if (!isntStarted)
			throw new IllegalStateException("服务已经启动。");
		this.logInfo("启动:" + this.getType().getDisplayName() + "服务。");
		this.startInner();
	}

	public void stopService()
	{
		this.logInfo("开始停止服务: " + this.getType().getDisplayName());
		synchronized (this)
		{
			if (!this.isStarted())
				this.logInfo("该服务已经停止，忽略尝试。");
			this.stopInner();
			isStarted.set(false);
		}
	}

	/**
	 * 一些需要启动的事情。由子类实现，基类中的startService方法会调用该方法。
	 */
	protected abstract void startInner();

	/**
	 * 一些需要停止的事情。由子类实现，基类中的stopService方法会调用该方法。
	 */
	protected abstract void stopInner();

	// = 日志接口(ILog)的实现 ============

	@Override
	public void logDebug(final Object message)
	{
		LogHelper.logDebug(this, message);
	}

	@Override
	public void logDebug(final Object message, final Throwable t)
	{
		LogHelper.logDebug(this, message, t);
	}

	@Override
	public void logError(final Object message)
	{
		LogHelper.logError(this, message);
	}

	@Override
	public void logError(final Object message, final Throwable t)
	{
		LogHelper.logError(this, message, t);
	}

	@Override
	public void logInfo(final Object message)
	{
		LogHelper.logInfo(this, message);
	}

	@Override
	public void logInfo(final Object message, final Throwable t)
	{
		LogHelper.logInfo(this, message, t);
	}

	@Override
	public void logWarn(final Object message)
	{
		LogHelper.logWarn(this, message);
	}

	@Override
	public void logWarn(final Object message, final Throwable t)
	{
		LogHelper.logWarn(this, message, t);
	}

}
